package net.neptech.util;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import net.neptech.model.dto.node.*;
import net.neptech.enums.workflow.InstanceConstant;
import net.neptech.enums.workflow.NodeTypeEnum;
import net.neptech.model.dto.ConditionNode;
import net.neptech.model.workflow.Workflow;
import net.neptech.service.WorkflowService;
import net.neptech.model.vo.FormVO;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @Author Saya
 * @Date 2025/8/18 16:19
 * @Description TODO
 **/
public class NodeUtil {
    /**
     * 一直到最上层的节点
     */
    public static List<Node> getParentNodeUntilRoot(Node node, String nodeId) {
        List<Node> nodeList = new ArrayList<>();
        while (true) {
            Node parentNode = getParentNode(node, nodeId, true);
            if (isNode(parentNode)) {
                nodeList.add(parentNode);
                nodeId = parentNode.getId();
            } else {
                break;
            }
        }
        return nodeList;
    }
    /**
     * 获取父级节点
     */
    public static Node getParentNode(Node node, String nodeId, boolean containEmptyNode) {
        if (!isNode(node)) {
            return null;
        }
        Node childNode = node.getChildNode();
        if (isNode(childNode) && childNode.getId().equals(nodeId)) {
            return node;
        }
        Integer type = node.getType();
        if (NodeTypeEnum.getByValue(type).getBranch()) {
            ConditionNode conditionNode = (ConditionNode) node;
            //条件分支
            List<Node> branches = conditionNode.getConditionList();
            for (Node branch : branches) {
                if (containEmptyNode) {
                    if (isNode(branch) && branch.getId().equals(nodeId)) {
                        return node;
                    }
                    Node parentNode = getParentNode(branch, nodeId, containEmptyNode);
                    if (parentNode != null) {
                        return parentNode;
                    }
                    continue;
                }
                Node children = branch.getChildNode();
                if (isNode(children) && children.getId().equals(nodeId)) {
                    return node;
                }
                Node parentNode = getParentNode(children, nodeId, containEmptyNode);
                if (parentNode != null) {
                    return parentNode;
                }
            }
        }
        return getParentNode(childNode, nodeId, containEmptyNode);
    }

    public static Node getNode(Node node, String nodeId, boolean containEmptyNode) {
        if (!isNode(node)) {
            return null;
        }
        if (node.getId().equals(nodeId)) {
            return node;
        }
        Node childNode = node.getChildNode();
        Integer type = node.getType();
        if (NodeTypeEnum.getByValue(type).getBranch()) {
            ConditionNode conditionNode = (ConditionNode) node;
            //条件分支
            List<Node> branches = conditionNode.getConditionList();
            for (Node branch : branches) {
                if (containEmptyNode) {
                    Node parentNode = getNode(branch, nodeId, containEmptyNode);
                    if (parentNode != null) {
                        return parentNode;
                    }
                    continue;
                }
                Node children = branch.getChildNode();
                Node parentNode = getNode(children, nodeId, containEmptyNode);
                if (parentNode != null) {
                    return parentNode;
                }
            }
        }
        return getNode(childNode, nodeId, containEmptyNode);
    }
    /**
     * 添加结束节点
     *
     * @param node 需要配置为结束的node
     */
    public static void addEndNode(Node node) {
        Node children = node.getChildNode();
        if (isNode(children)) {
            addEndNode(children);
        } else {
            Node end = new EndNode();
            end.setId(InstanceConstant.VariableKey.END);
            end.setType(NodeTypeEnum.END.getValue());
            end.setNodeName("结束节点");
            end.setParentId(node.getId());
            node.setChildNode(end);
        }
    }
    public static boolean isNode(Node childNode) {
        return childNode != null && childNode.getId() != null;
    }

    /**
     * 处理父级id
     *
     * @param node node对象
     */
    public static void handleParentId(Node node, String parentId) {
        if (!isNode(node)) {
            return;
        }
        node.setParentId(parentId);
        node.setTempId(StrUtil.format("{}|{}", node.getId(), IdUtil.fastSimpleUUID()));
        Integer type = node.getType();
        if (NodeTypeEnum.getByValue(type).getBranch()) {
            ConditionNode conditionNode = (ConditionNode) node;
            //分支
            List<Node> branches = conditionNode.getConditionList();
            for (Node branch : branches) {
                branch.setParentId(node.getId());
                Node children = branch.getChildNode();
                handleParentId(children, branch.getId());
            }
        }
        handleParentId(node.getChildNode(), node.getId());
    }

    /**
     * 处理节点添加执行id和流程唯一id
     */
    public static void handleNodeAddExecutionId(Node node, String nodeId, String executionId) {
        //非空判断
        if (!isNode(node)) {
            return;
        }
        //判断是否根节点
        if ((!Convert.toBool(node.isRemarkedAtNodeShow(), false)) && (((StrUtil.contains(nodeId, node.getId()) && StrUtil.startWith(nodeId, InstanceConstant.VariableKey.START_NODE)) || (StrUtil.equals(nodeId, node.getId()))) && StrUtil.isBlank(node.getExecutionId()))) {
            //操作根节点
            node.setExecutionId(executionId);
            return;
        }
        Integer type = node.getType();
        if (NodeTypeEnum.getByValue(type).getBranch()) {
            ConditionNode conditionNode = (ConditionNode) node;
            //条件分支
            List<Node> branches = conditionNode.getConditionList();
            if (CollUtil.isNotEmpty(branches)) {
                for (Node branch : branches) {
                    Node children = branch.getChildNode();
                    handleNodeAddExecutionId(children, nodeId, executionId);
                }
            }
        }
        handleNodeAddExecutionId(node.getChildNode(), nodeId, executionId);
    }

    /**
     * 根据nodeId 获取最终的nodeId列表
     */
    public static List<String> getFinalNodeIdList(String nodeId) {
        if (StrUtil.startWith(nodeId, InstanceConstant.VariableKey.START_NODE)) {
            return CollUtil.newArrayList(InstanceConstant.VariableKey.START_NODE, StrUtil.format("{}_user_task", InstanceConstant.VariableKey.START_NODE));
        }
        return CollUtil.newArrayList(nodeId);
    }
    /**
     * 处理发起人节点表单
     */
    public static void handleStarterForm(RootNode node, List<FormVO> formVOList) {
        Map<String, String> formPerms = node.getFormPerms();
        handlerPerm(formVOList, formPerms, InstanceConstant.FormPermClass.EDIT);
    }
    private static void handlerPerm(List<FormVO> formVOList, Map<String, String> formPerms, String defaultPerm) {
        for (FormVO formVO : formVOList) {
            formPerms.putIfAbsent(formVO.getFormId(), defaultPerm);
        }
    }
    /**
     * 处理用户任务节点的表单--如果没设置上 默认是只读
     *
     * @param node 跟节点
     */
    public static void handleApproveForm(Node node, List<FormVO> formVOList) {
        if (!isNode(node)) {
            return;
        }
        Integer type = node.getType();
        if (type.intValue() == NodeTypeEnum.APPROVAL.getValue()) {
            //审批节点
            //当前节点的权限

            ApproveNode approveNode = (ApproveNode) node;

            Map<String, String> formPerms = approveNode.getFormPerms();

            handlerPerm(formVOList, formPerms, InstanceConstant.FormPermClass.READ);

        }
        if (NodeTypeEnum.getByValue(type).getBranch()) {

            ConditionNode conditionNode = (ConditionNode) node;
            //分支
            List<Node> branches = conditionNode.getConditionList();
            for (Node branch : branches) {
                branch.setParentId(node.getId());
                Node children = branch.getChildNode();
                handleApproveForm(children, formVOList);
            }

        }
        handleApproveForm(node.getChildNode(), formVOList);
    }

    /**
     * 处理抄送节点的表单--如果没设置上 默认是只读
     *
     * @param node 跟节点
     */
    public static void handleCopyForm(Node node, List<FormVO> formVOList) {
        if (!isNode(node)) {
            return;
        }
        Integer type = node.getType();
        if (type.intValue() == NodeTypeEnum.CC.getValue()) {
            //审批节点
            //当前节点的权限
            CopyNode copyNode = (CopyNode) node;
            Map<String, String> formPerms = copyNode.getFormPerms();
            handlerPerm(formVOList, formPerms, InstanceConstant.FormPermClass.READ);

        }
        if (NodeTypeEnum.getByValue(type).getBranch()) {
            ConditionNode conditionNode = (ConditionNode) node;
            //分支
            List<Node> branches = conditionNode.getConditionList();
            for (Node branch : branches) {
                branch.setParentId(node.getId());
                Node children = branch.getChildNode();
                handleCopyForm(children, formVOList);
            }
        }
        handleCopyForm(node.getChildNode(), formVOList);
    }


    /**
     * 如果下级不是节点 设置为null
     */
    public static void handEmptyNode(Node node) {
        if (!isNode(node)) {
            return;
        }
        if (!isNode(node.getChildNode())) {
            node.setChildNode(null);
            return;
        }
        Integer type = node.getType();
        if (NodeTypeEnum.getByValue(type).getBranch()) {
            ConditionNode conditionNode = (ConditionNode) node;

            //分支
            List<Node> branches = conditionNode.getConditionList();
            for (Node branch : branches) {
                branch.setParentId(node.getId());
                Node children = branch.getChildNode();
                handEmptyNode(children);
            }
        }
        handEmptyNode(node.getChildNode());
    }

    /**
     * 处理用户任务节点
     *
     * @param node 跟节点
     */
    public static void handleApprove(Node node) {
        if (!isNode(node)) {
            return;
        }
        Integer type = node.getType();
        if (NodeTypeEnum.getByValue(type).getBranch()) {
            ConditionNode conditionNode = (ConditionNode) node;
            //分支
            List<Node> branches = conditionNode.getConditionList();
            for (Node branch : branches) {
                branch.setParentId(node.getId());
                Node children = branch.getChildNode();
                handleApprove(children);
            }
        }
        handleApprove(node.getChildNode());
    }

    public static String getLastNodeId(String flowId, String nodeId, String parentNodeId) {
        if (StrUtil.isNotBlank(parentNodeId)) {
            return parentNodeId;
        }
        WorkflowService workflowService = SpringUtil.getBean(WorkflowService.class);
        Workflow workflow = workflowService.getByFlowId(flowId);
        Node node = JsonUtil.parseObject(workflow.getFlow(), Node.class);
        Node parentNode = getParentNode(node, nodeId, false);
        if (parentNode == null) {
            return null;
        }
        return parentNode.getId();
    }
}

